﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Syndication;
using System.Xml.Linq;
using PBDesk.Business.FeedsAggregator.Entities;
using System.Xml;
using PBDesk.Utilities;
using System.Net;


namespace PBDesk.Business.FeedsAggregator.Helper
{
    public class FeedHelper
    {
        #region GetFeeds
        public static SyndicationFeedFormatter GetFeeds(string x)
        {
            SyndicationFeed feed = new SyndicationFeed("Feeds X=" + x, "Description of ", null);
            List<SyndicationItem> items = new List<SyndicationItem>();


            SyndicationItem item = new SyndicationItem("An item for categoryName=" + x, "Item content :" + x, null);
            items.Add(item);
            feed.Items = items;

            return new Rss20FeedFormatter(feed);
        }

        public static SyndicationFeedFormatter GetFeeds(FeedCategory category, int count)
        {
           

            SyndicationFeed feed = null;
            if (category != null)
            {
                feed = new SyndicationFeed(category.Title, category.Description, category.Link);

                switch (category.Name)
                {
                    case "rss":
                        {
                            feed.Items = GetDefaultFeedItems(count);
                            break;
                        }
                    case "feed404":
                        {
                            feed.Items = Get404FeedItems();
                            break;
                        }
                    default:
                        {
                            using (WebClient client = new WebClient())
                            {
                                var newFeeds = from feedItem in category.FeedItems
                                               from xr in CustomXmlReader.Create(feedItem.Url).Kill()
                                               let sFeed = SyndicationFeed.Load(xr)
                                               from sFeedItem in sFeed.Items.OrderByDescending(dt => dt.PublishDate).Take(count)
                                               select sFeedItem;

                                feed.Items = newFeeds.OrderByDescending(dt => dt.PublishDate).Take(count);
                            }
                            break;
                        }
                }               

                feed.Generator = SyndicationHelper.GetFeedGenerator();
                feed.Authors.Add(SyndicationHelper.GetSyndicationPerson());
                feed.ImageUrl = category.ImageUrl;

                //var items = from url in feeds from xr in XmlReader.Create(url).Use() let feed = SyndicationFeed.Load(xr) from newFeeds in feed.Items select newFeeds; 

            }
            if (feed == null)
            {
                throw new Exception("error thrown");
            }
            return new Rss20FeedFormatter(feed);
        }
        #endregion

        #region Default Feeds /Rss
        internal static IEnumerable<SyndicationItem> GetDefaultFeedItems(int itemCount = SyndicationHelper.DEFAULT_FEED_ITEM_COUNT)
        {
            SyndicationFeed feed = new SyndicationFeed("title", "description", null);
            IEnumerable<SyndicationItem> blogFeed = GetPBDeskBlogFeeds(itemCount);
            SyndicationFeed twitterFeed = GetTwitterFeeds("pbdesk", itemCount/2);
            IEnumerable<SyndicationItem> customFeed = GetPBDeskCustomFeeds(itemCount);

            feed.Items = blogFeed.Union(twitterFeed.Items).Union(customFeed);
            feed.Items = feed.Items.OrderByDescending(dt => dt.PublishDate).Take(itemCount);

            return feed.Items;

        }

        internal static IEnumerable<SyndicationItem> GetPBDeskCustomFeeds(int itemCount = SyndicationHelper.DEFAULT_FEED_ITEM_COUNT)
        {

            IEnumerable<SyndicationItem> returnList = GetCustomFeedItems("CustomPBDeskFeeds.xml");


            return returnList.OrderByDescending(dt => dt.PublishDate).Take(itemCount);
        }

        internal static IEnumerable<SyndicationItem> GetPBDeskBlogFeeds(int count = 20)
        {
            string feedUrl = string.Format("http://blog.pbdesk.com/feeds/posts/default?alt=rss&max-results={0}", count); 
            SyndicationFeed feed = SyndicationHelper.GetSyndicationFeedFromUrl(feedUrl, count);
            foreach (SyndicationItem item in feed.Items)
            {
                item.Authors.Clear();
                item.Authors.Add(SyndicationHelper.GetSyndicationPerson());

                StringBuilder labelText = new StringBuilder("Blog Post filed under Labels: ");
                foreach (SyndicationCategory category in item.Categories)
                {
                    labelText.Append(category.Name + ", ");
                }
                labelText = labelText.Remove(labelText.Length - 2, 2);
                item.Summary = new TextSyndicationContent(labelText.ToString(), TextSyndicationContentKind.Html);
                item.Categories.Add(new SyndicationCategory("Blog Post"));
                item.Title = new TextSyndicationContent("Blog Post: " + item.Title.Text);

            }
            return feed.Items;
        }


        #endregion

        #region Twitter Feeds

        internal static SyndicationFeed GetTwitterFeeds(string twitterHandle, int count = 20)
        {
            string feedUrl = string.Format("http://twitter.com/statuses/user_timeline/{0}.rss?count={1}", twitterHandle, count);

            SyndicationFeed feed = SyndicationHelper.GetSyndicationFeedFromUrl(feedUrl, count);
            foreach (SyndicationItem item in feed.Items)
            {
                item.Authors.Clear();
                item.Authors.Add(SyndicationHelper.GetSyndicationPerson());
                item.Categories.Add(new SyndicationCategory("Twitter Tweet"));
                item.Title = new TextSyndicationContent(item.Title.Text.Replace(twitterHandle + ":", "Twitter Tweet:"));
            }
            return feed;

        }

        #endregion

        #region 404 Feeds        

        internal static IEnumerable<SyndicationItem> Get404FeedItems()
        {
            return GetCustomFeedItems("Feeds404.xml");         
        }

        #endregion

        #region Custom Feeds

        internal static IEnumerable<SyndicationItem> GetCustomFeedItems(string resourceName)
        {
            List<SyndicationItem> returnList = new List<SyndicationItem>();
            SyndicationItem feedItem;
            XDocument xDoc = SyndicationHelper.GetXMLResource(resourceName);
            var feedItems = from e in xDoc.Descendants("item")
                            select new
                            {
                                title = e.Descendants("title").FirstOrDefault().Value,
                                description = e.Descendants("description").FirstOrDefault().Value,
                                link = e.Descendants("link").FirstOrDefault().Value,
                                pubDate = e.Descendants("pubDate").FirstOrDefault().Value
                            } as dynamic;
                    
            foreach (var item in feedItems)
            {
                feedItem = new SyndicationItem(item.title, item.description, new Uri(item.link));
                feedItem.PublishDate = DateTime.Parse(item.pubDate);
                returnList.Add(feedItem);
            }

            return returnList;
        }

        #endregion

        internal static Rss20FeedFormatter GetRssFeeds(RssChannel channel, List<FeedProvider> providers, int itemCount = SyndicationHelper.DEFAULT_FEED_ITEM_COUNT)
        {
            SyndicationFeed feed = new SyndicationFeed(channel.Title, channel.Description, channel.Link);
            feed.ImageUrl = channel.ImageUrl;

            List<SyndicationItem> feedItems = new List<SyndicationItem>();
            foreach (FeedProvider provider in providers)
            {
                switch (provider.Source)
                {
                    case FeedSource.Url:
                        {
                            break;
                        }
                    case FeedSource.Twitter:
                        {
                            break;
                        }
                }

            }

            feed.Items = feedItems;

            return new Rss20FeedFormatter(feed);
        }


        internal static Rss20FeedFormatter GetRssFeeds(SyndicationFeed feed, List<FeedProvider> providers, int itemCount)
        {
            List<SyndicationFeed> newFeed = new List<SyndicationFeed>();
            newFeed.Add(feed);

            foreach (FeedProvider provider in providers)
            {
                SyndicationFeed tFeed = GetFeedFromProviders(provider);
                if (tFeed != null && tFeed.Items.Count() > 0)
                {
                    if (tFeed.Categories.Count > 0)
                    {
                        
                        
                    }
                }
            }
            return null;
        }

        private static SyndicationFeed GetFeedFromProviders(FeedProvider provider)
        {
            throw new NotImplementedException();
        }

        private static SyndicationFeed GetFeedFromProviders(List<FeedProvider> providers)
        {
            throw new NotImplementedException();
        }
    }
}
